
package com.be.beadmin.project.impl;

import cn.hutool.core.util.ObjectUtil;
import com.be.beadmin.basicData.dto.input.UserDto;
import com.be.beadmin.basicData.dto.output.UserEx;
import com.be.beadmin.basicData.entity.User;
import com.be.beadmin.basicData.mapper.UserMapper;
import com.be.beadmin.basicData.repository.RoleRepository;
import com.be.beadmin.basicData.repository.UserRepository;
import com.be.beadmin.basicData.service.UserService;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaQueryBuilderNew;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.project.Util.BeanCopyUtils;
import com.be.beadmin.project.dto.input.*;
import com.be.beadmin.project.dto.output.InfoAndPayEx;
import com.be.beadmin.project.dto.output.InfoCodeEx;
import com.be.beadmin.project.dto.output.InfoEx;
import com.be.beadmin.project.dto.output.UserInfoSimpEx;
import com.be.beadmin.project.entity.*;
import com.be.beadmin.project.mapper.BatchProductMapper;
import com.be.beadmin.project.mapper.InfoMapper;
import com.be.beadmin.project.mapper.InfoMapperEx;
import com.be.beadmin.project.mapper.PayInfoMapperEx;
import com.be.beadmin.project.repository.*;
import com.be.beadmin.project.service.*;
import com.be.beadmin.service.constant.UserConst;
import com.be.beadmin.service.dto.input.SerialNumberDto;
import com.be.beadmin.service.entity.DictData;
import com.be.beadmin.service.entity.DictType;
import com.be.beadmin.service.impl.MinioService;
import com.be.beadmin.service.repository.DictDataRepository;
import com.be.beadmin.service.repository.DictTypeRepository;
import com.be.beadmin.service.service.SerialNumberService;
import com.be.beadmin.service.util.DateUtil;
import io.minio.errors.*;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.math3.stat.descriptive.summary.Product;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;
import java.io.IOException;
import java.net.BindException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zmy
 * @description 服务实现
 * @date 2023-01-13
 **/
@Service
@RequiredArgsConstructor
public class InfoServiceImpl implements InfoService {

    @Autowired
    private InfoRepository infoRepository;

    @Autowired
    private InfoMapper infoMapper;
    @Autowired
    private InfoMapperEx infoExMapper;

    @Autowired
    private PayInfoService payInfoService;

    @Autowired
    private PayInfoRepository payInfoRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private PayInfoMapperEx payInfoMapperEx;
    @Autowired
    private SerialNumberService serialNumberService;

    @Autowired
    private MinioService minioService;
    private String reviewBucketName = "reviewfile";
    @Autowired
    private UserService userService;
    @Autowired
    private TeamInfoService teamInfoService;
    @Autowired
    private TeamService teamService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private BatchProductService batchProductService;

    @Autowired
    private BatchProductRepository batchProductRepository;
    @Autowired
    private BatchProductMapper batchProductMapper;
    @Autowired
    private ProductInfoRepository productInfoRepository;
    @Autowired
    private MasterPlanRepository masterPlanRepository;
    @Autowired
    private TeamInfoRepository teamInfoRepository;
    @Autowired
    private TeamRepository teamRepository;
    @Autowired
    private BatchPlanRepository batchPlanRepository;
    @Autowired
    private DictTypeRepository dictTypeRepository;

    @Autowired
    private DictDataRepository dictDataRepository;
    @Autowired
    private PlanStageRepository planStageRepository;
    @Autowired
    private MasterPlanService masterPlanService;
//    @Autowired
//    private MasterPlanRepository masterPlanRepository;

    @Override
    public Page<InfoEx> getInfoByPage(PageEntity pageEntity) {
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<Info> page = infoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilderNew.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(Info_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(Info_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<InfoEx> page1 = page.map(infoExMapper::toEntity);
        return page1;

    }

    @Override
    public Page<Info> getInfoByPageOrigin(PageEntity pageEntity) {
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<Info> page = infoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(Info_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(Info_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
//        Page<InfoEx> page1 = page.map(infoExMapper::toEntity);
        return page;

    }

    @Transactional
    @SneakyThrows
    @Override
    public int addInfo(InfoDto infoDto) {
        int res;


        // -------- 1. 查询数据库指定id的项目存不存在， 如果存在说明刚刚添加过
        Info result = infoRepository.findInfoByIdAndDelete(infoDto.getId(), 0);
        if (ObjectUtil.isNotEmpty(result)) {
            throw new BeadminException("Info不存在,请重新查询");
        }
        Info nameInfo = infoRepository.findInfoByProjectNameAndDelete(infoDto.getProjectName(), 0);
        if (nameInfo != null)
            throw new BeadminException("该项目名称[" + infoDto.getProjectName() + "]已存在，请更换项目名称");

        // 将项目状态设置为已发布
        infoDto.setContractState("待审核");

        // -------- 2 将DTo装化成entity类  可以进行存储的对象
        Info info = infoMapper.toEntity(infoDto);
//            info.setProjectCode(;

        // 添加默认团队

        teamService.setInfoDefaultTeam(info);
        info.setCustomerCode(serialNumberService.getNextSnByCode("CustomerCode"));
//            info.setContractAmount(info.getContractAmount()+"万");
        info.setContractState("已发布");
        // --------  3 保存该项目进数据库
        Info save = infoRepository.save(info);


        // 可以先不管这些东西
        serialNumberService.getNextSnByCode("ContractCode");
        serialNumberService.getNextSnByCode("InfoCode");

        // 这里生成一个该项目专属的流水号编码
        // 不可在前端查找到
        serialNumberService.addSerialNumber(new SerialNumberDto(save.getId()+"_BP_Code",save.getProjectName()+"-批次计划流水码",3,1));


        serialNumberService.addSerialNumber(new SerialNumberDto(save.getId()+"_P_Code",save.getProjectName()+"-柜体流水码",3,1));

        serialNumberService.addSerialNumber(new SerialNumberDto(save.getId()+"_B_Code",save.getProjectName()+"-bom流水码",3,1));

        serialNumberService.addSerialNumber(new SerialNumberDto(save.getId()+"_D_Code",save.getProjectName()+"-图纸流水码",3,1));

        serialNumberService.addSerialNumber(new SerialNumberDto(save.getId()+"_WO_Code",save.getProjectName()+"-工单流水码",3,1));

        // 6. 主计划添加
        // 生成推荐主计划 // 批次计划添加
        res = masterPlanService.addMasterPlan(save.getId());

        return res;

    }

    @Transactional
    @Override
    public void updateInfo(InfoDto infoDto) {
        Info info = infoRepository.findInfoById(infoDto.getId());

        if(DateUtil.transDateFormat(infoDto.getDeliveryDate()).compareTo(DateUtil.transDateFormat(info.getDeliveryDate()))!= 0){
            // 1- 修改主计划表中的项目交付日期
            MasterPlan masterPlan = masterPlanRepository.findMasterPlanByInfoIdAndDelete(info.getId(), 0);
            masterPlan.setDeliveryDate(infoDto.getDeliveryDate());
            masterPlanRepository.save(masterPlan);

            // 2- 修改主计划表中的交货日期，同时逆向推算
//            PlanStage deliverPlanStage = planStageRepository.findPlanStageByPlanIdAndStageNameAndDelete(masterPlan.getId(), "发货日期", 0);
//            deliverPlanStage.setStagePlanEndTime(infoDto.getDeliveryDate());
//            planStageRepository.save(deliverPlanStage);
            // 设置工时

            // 降序排序各阶段,交货日期为第一个
            List<PlanStage> planStages = planStageRepository.findPlanStagesByPlanIdAndDeleteOrderByStageSortDesc(masterPlan.getId(),0);
            for (int i = 0; i < planStages.size(); i++) {
                PlanStage planStage = planStages.get(i);
                if (i == 0) {
                    planStage.setStagePlanEndTime(DateUtil.computeDate(infoDto.getDeliveryDate(),0));
                } else {
                    planStage.setStagePlanEndTime(DateUtil.computeDate(planStages.get(i-1).getStagePlanStartTime(),-1*24));
                }
                planStage.setStagePlanStartTime(DateUtil.computeDate(planStage.getStagePlanEndTime(),-1 * planStage.getStageDuration() *24 ));
            }
            planStageRepository.saveAll(planStages);

            //3- 修改批次计划表中的项目交付日期
            List<BatchPlan> batchPlans = batchPlanRepository.findBatchPlanByMasterPlanIdAndDelete(masterPlan.getId(),0);
            List<BatchPlan> batchPlansUpdated = batchPlans.stream().peek(s -> s.setInfoDeliveryDate(infoDto.getDeliveryDate())).collect(Collectors.toList());
            batchPlanRepository.saveAll(batchPlansUpdated);
        }

        BeanUtils.copyProperties(infoDto,info,BeanCopyUtils.getNullPropertyNames(infoDto));
        infoRepository.save(info);
    }


//    @Transactional
//    @Override
//    public void delInfo(HttpServletRequest request,String id) {
//        if(!userService.isRole(request, UserConst.ADMINROLECODE)) throw new BeadminException("不是系统管理不允许删除！！");
//
//        // 1. 找到该项目
//        Info info = infoRepository.findInfoById(id);
//        // 删除项目下的所有东西
//        MasterPlan masterPlan = masterPlanRepository.findMasterPlanByInfoIdAndDelete(id, 0);
//        List<String> batchPlanIdList = batchPlanRepository.findBatchPlanIdByMasterPlanIdAndDelete(masterPlan.getId(), 0);
//        // 删除该项目的所有流水编码
//        serialNumberService.deleteSerialNumberByInfo(info.getId());
//
//        // 删除批次柜体
//        batchProductService.deleteBatchProductAndRelationInfo(info);
//
//
//        // 删除批次计划
//        batchPlanRepository.deleteBatchPlanByInfoIdAndDelete(1, info.getId(), 0);
//        // 删除主计划
//        masterPlanRepository.deleteMasterPlanByInfoIdAndDelete(1, info.getId(), 0);
//        // 删除导入的柜体信息
//        productInfoRepository.deleteProductInfoByInfoIdAndDelete(1, info.getId(), 0);
//        // 删除所有计划的阶段
//        planStageRepository.deletePlanStageByPlanIdAndDelete(1,masterPlan.getId(),0);
//        planStageRepository.deletePlanStageByPlanIdInAndDelete(1,batchPlanIdList,0);
//        // 删除所有工单
//
//        // 删除所有分料信息
//        // 删除所有客户投诉信息
//        // 删除所有接线错误信息
//        // 删除所有工序信息
//        // 删除所有的检验单信息
//
//        // 2. 将项目的删除字段设置1， 表示已删除
//        info.setDelete(1);
//        // 3. 保存到数据库中
//        infoRepository.save(info);
//    }

    @Override
    public void delInfos(List<String> ids) {
    }

//    @Override
//    public void genenateProductAll(List<ProductInfo> productInfos) {
////        for (ProductTotalInfo productTotalInfo : productTotalInfos) {
////            genenateProduct(productTotalInfo);
////        }
//        List<BatchProductDto> batchProductDtos = new ArrayList<>();
//        for (ProductInfo productInfo : productInfos) {
////            genenateProduct(productTotalInfo);
//            if (productInfo.getIsPublished() == 0) {
//                BatchProductDto batchProductDto = new BatchProductDto();
//                if (productInfo.getIsStandard() == 1) {
//                    StandProduct standProduct = standProductRepository.findStandProductByStandTypeCodeAndDelete(productInfo.getStandTypeCode(), 0);
//                    if (standProduct == null) throw new BeadminException("未找到标准柜体");
//                    batchProductDto.setStandardProductCode(productInfo.getStandTypeCode());
//                }
//
//                batchProductDto.setInfoId(productInfo.getInfoId());
//                batchProductDto.setProductCode(productInfo.getProductCode());
//                batchProductDto.setProductType(productInfo.getProductType());
//                batchProductDto.setBatchPlanId("-1");
//                batchProductDto.setIsStandard(BigDecimal.valueOf(productInfo.getIsStandard()));
//                batchProductDto.setProjectName(productInfo.getProjectName());
//                batchProductDtos.add(batchProductDto);
//                productInfo.setIsPublished(1);
//                productInfoRepository.save(productInfo);
//            }
//
//        }
//        List<BatchProduct> batchProducts = batchProductMapper.toEntity(batchProductDtos);
//        batchProductRepository.saveAll(batchProducts);
//    }

//    /**
//     * 根据录入的单条柜体总体的信息，存入多个柜体
//     *
//     * @param productTotalInfo
//     */
//    @Override
//    public void genenateProduct(ProductTotalInfo productTotalInfo) {
//        int count = productTotalInfo.getProductQty();
//        List<BatchProductDto> batchProductDtos = new ArrayList<>();
//        for (int i = 0; i < count; i++) {
//            BatchProductDto batchProduct = new BatchProductDto();
//            if (productTotalInfo.getInfoId() != null) {
//                batchProduct.setInfoId(productTotalInfo.getInfoId());
//            }
//            if (productTotalInfo.getProjectName() != null) {
//                batchProduct.setProjectName(productTotalInfo.getProjectName());
//            }
//            if (productTotalInfo.getProductType() != null) {
//                batchProduct.setProductType(productTotalInfo.getProductType());
//            }
//            batchProduct.setIsStandard(BigDecimal.valueOf(productTotalInfo.getIsStandard()));
//            batchProduct.setProductCode(serialNumberService.getNextSnByCode("BatchProduct"));
//            batchProduct.setBatchPlanId("-1");
//            batchProductDtos.add(batchProduct);
//        }
//        List<BatchProduct> batchProducts = batchProductMapper.toEntity(batchProductDtos);
//        batchProductRepository.saveAll(batchProducts);
//
//    }

    @Override
    public InfoCodeEx getContractAndInfoCodeNext() {
        InfoCodeEx infoCodeEx = new InfoCodeEx();
        infoCodeEx.setContractCode(serialNumberService.getNextSnByCodeNotSave("ContractCode"));
        infoCodeEx.setProjectCode(serialNumberService.getNextSnByCodeNotSave("InfoCode"));

        return infoCodeEx;//获取合同编码;
    }

    /**
     * 暂停执行项目
     *
     * @param infoId
     * @return
     */
    @Override
    public Info pauseOrStartProject(String infoId) {
        Info info = infoRepository.findInfoByIdAndDelete(infoId, 0);
        if (info == null) throw new BeadminException("未找到该项目");
        if (info.getContractState().equals("未发布")) throw new BeadminException("项目还未发布");
        if (info.getContractState().equals("已暂停")) {
            info.setContractState("已发布");
        } else if (info.getContractState().equals("已发布")) {
            info.setContractState("已暂停");
        }

        infoRepository.save(info);
        return info;
    }

    /**
     * 获取所有项目的项目名称和编码
     *
     * @return
     */
    @Override
    public List<ProjectNameAndCode> getProjectNameAndCodeSimp() {
        List<Info> infoList = infoRepository.findAll();
        List<ProjectNameAndCode> projectNameAndCodes = new ArrayList<>();
        for (int i = 0; i < infoList.size(); i++) {
            ProjectNameAndCode projectNameAndCode = new ProjectNameAndCode();
            projectNameAndCode.setInfoId(infoList.get(i).getId());
            projectNameAndCode.setProjectName(infoList.get(i).getProjectName());
            projectNameAndCode.setProjectCode(infoList.get(i).getProjectCode());
            projectNameAndCode.setCustomerName(infoList.get(i).getCustomerName());
//            projectInfoSimp.setInfoId(infoList.get(i).getProjectCode());
            if (infoList.get(i).getDelete() == 0) {
                projectNameAndCodes.add(projectNameAndCode);
            }

        }

        return projectNameAndCodes;
    }

    /**
     * 新增项目信息包含付款信息
     *
     * @param infoAndPayDto
     * @return
     */
    @Transactional
    @Override
    public int addInfoAndPay(InfoAndPayDto infoAndPayDto) {
        int res;

        InfoDto infoDto = infoAndPayDto.getInfoDto();
        PayInfoDto payInfoDto = infoAndPayDto.getPayInfoDto();
        // -------- 1. 查询数据库指定id的项目存不存在， 如果存在说明刚刚添加过
        Info result = infoRepository.findInfoByIdAndDelete(infoDto.getId(), 0);
        if (ObjectUtil.isNotEmpty(result)) {
            throw new BeadminException("Info不存在,请重新查询");
        }
        Info nameInfo = infoRepository.findInfoByProjectNameAndDelete(infoDto.getProjectName(), 0);
        if (nameInfo != null)
            throw new BeadminException("该项目名称[" + infoDto.getProjectName() + "]已存在，请更换项目名称");

        // 将项目状态设置为已发布
        infoDto.setContractState("已发布");

        // -------- 2 将DTo装化成entity类  可以进行存储的对象
        Info info = infoMapper.toEntity(infoDto);
//            info.setProjectCode(;

        // 添加默认团队
        List<Team> list = teamRepository.findTeamByTeamNameAndDelete("默认团队", 0);
        if (list.size() == 0) throw new BeadminException("没有默认团队，请先添加一个默认团队");
        info.setTeamId(list.get(0).getId()); //默认团队
        info.setCustomerCode(serialNumberService.getNextSnByCode("CustomerCode"));
//            info.setContractAmount(info.getContractAmount()+"万");


        // --------  3 保存该项目进数据库
        Info save = infoRepository.save(info);

        // 可以先不管这些东西
        serialNumberService.getNextSnByCode("ContractCode");
        serialNumberService.getNextSnByCode("InfoCode");


        // 6. 主计划添加
        // 生成推荐主计划 // 批次计划添加
        res = masterPlanService.addMasterPlan(save.getId());

        //
        payInfoDto.setInfoId(save.getId());
        payInfoService.addPayInfo(payInfoDto);

        return res;
    }

    @Override
    public Page<InfoAndPayEx> getInfoAndPayByPage(PageEntity pageEntity) {
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<Info> page = infoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(Info_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(Info_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
//        Page<InfoEx> page1 = page.map(infoExMapper::toEntity);
        Page<InfoAndPayEx> map = page.map(new Function<Info, InfoAndPayEx>() {
            @Override
            public InfoAndPayEx apply(Info info) {
                InfoAndPayEx infoAndPayEx = new InfoAndPayEx();
                infoAndPayEx.setInfoEx(infoExMapper.toEntity(info));
                PayInfo payInfo = payInfoRepository.findPayInfoByInfoIdAndDelete(info.getId(), 0);
                infoAndPayEx.setPayInfoEx(payInfoMapperEx.toEntity(payInfo));


                return infoAndPayEx;
            }
        });
        return map;
    }

    /**
     * 项目审核
     *
     * @param infoId
     * @param reviewMemo
     * @param multipartFile
     */
    @Override
    public void infoReview(String infoId, String reviewMemo, MultipartFile multipartFile) throws InvalidBucketNameException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        Info info = infoRepository.findInfoByIdAndDelete(infoId, 0);
        if (info == null ) throw new BeadminException("未找到该项目");
        if (!info.getContractState().equals("待审核")) throw new BeadminException("该项目已审核，请勿重复审核");
        //设置审核备注
        info.setReviewMemo(reviewMemo);
        //设置审核人员
//        info.setReviewEditor(userService.ge);
        //设置审核状态（审核结果）
        info.setContractState("已发布");
        //设置审核时间
        String now = DateUtil.getNow();
        info.setReviewTime(new Date());
        //设置审核附件
        if (!multipartFile.isEmpty()) {
            String originalFilename = multipartFile.getOriginalFilename();
            info.setReviewFileId(infoId + "-" + originalFilename);
            //上传审核附件
            minioService.uploadFile(reviewBucketName, infoId + "-" + originalFilename, multipartFile);
        }

        //更新数据库
        infoRepository.save(info);


    }

    /**
     * 获取指定用户的所有项目信息
     *
     * @param user
     * @return
     */
    @Override
    public List<InfoEx> getInfoByUser(User user) {
        List<String> teamIdList = teamInfoRepository.findUniqueTeamIdByUserIdAndDelete(user.getId(), 0);
        List<Info> infoList = infoRepository.findInfosByTeamIdInAndDelete(teamIdList, 0);
        return infoExMapper.toEntity(infoList);
    }

    /**
     * 获取当前用户的所有项目信息
     *
     * @param request
     * @return
     */
    @Override
    public List<InfoEx> getInfoByCurrentUser(HttpServletRequest request) {
        UserEx userEx = userService.viewBaseInfo(request);
        return getInfoByUser(userMapper.toDto(userEx));
    }

    /**
     * 获取当前用户的所有项目Id
     *
     * @param request
     * @return
     */
    @Override
    public List<String> getInfoIdByCurrentUser(HttpServletRequest request) {
        UserEx userEx = userService.viewBaseInfo(request);
        List<String> teamIdList = teamInfoRepository.findUniqueTeamIdByUserIdAndDelete(userMapper.toDto(userEx).getId(), 0);
        if (teamIdList.size() == 0) {
            return null;
        }
        List<String> infoIdList = infoRepository.findUniqueInfoIdsByTeamIdInAndDelete(teamIdList, 0);
        return infoIdList;
    }

    /**
     * 获取id的项目信息
     *
     * @param id
     * @return
     */
    @Override
    public Info getInfoIdById(String id) {
        Info info = infoRepository.findInfoByIdAndDelete(id, 0);
        if (info == null) {
            throw new BeadminException("找到项目id");
        }
        return info;
    }

    /**
     * 根据项目ID获取该项目的所有用户
     *
     * @param infoId
     * @return
     */
    @Override
    public List<UserInfoSimpEx> getUsersByInfoId(String infoId) {
        List<UserInfoSimpEx> userList = new ArrayList<>();
        boolean isSame = false;
        for (TeamInfo teamInfo : teamInfoService.getTeamInfoByInfoId(infoId)) {
            User user = userService.getUserById(teamInfo.getUserId());
            if(user!=null){
                for (UserInfoSimpEx user1:
                        userList) {
                    if (user1.getUserId().equals(user.getId())) {
                        isSame = true ;
                    }
                }
                if (!isSame) {
                    UserInfoSimpEx userInfoSimpEx = new UserInfoSimpEx(user.getId(),user.getName());
                    userList.add(userInfoSimpEx);
                }

            }
        }
        return userList;
    }
    @Override
    public ArrayList<Integer> getInfoProgress() {
        Integer infoNumber = infoRepository.countInfoByDelete(0);
        Integer unfinishedInfoNumber = infoRepository.countInfoByDelete(0) - infoRepository.countInfoByContractStateAndDelete("完成",0);
        Integer finishedInfoNumber = infoRepository.countInfoByContractStateAndDelete("完成",0);
        ArrayList<Integer> infoProgress = new ArrayList<>();
        infoProgress.add(0,infoNumber);
        infoProgress.add(1,unfinishedInfoNumber);
        infoProgress.add(2,finishedInfoNumber);
        return infoProgress;
    }

    @Override
    public Info getInfoByProjectCode(String projectCode) {
        Info info = infoRepository.findInfoByProjectCodeAndDelete(projectCode, 0);
        if (info == null) {
            throw new BeadminException("未找到该项目");
        }
        return info;
    }

    @Override
    public Info shutOrStartProject(String infoId) {
        Info info = infoRepository.findInfoByIdAndDelete(infoId, 0);
        if (info == null) throw new BeadminException("未找到该项目");
        if (info.getContractState().equals("未发布")) throw new BeadminException("项目还未发布");
        if (!info.getContractState().equals("已关闭")) {
            info.setContractState("已关闭");
        } else {
            info.setContractState("已发布");
        }

        infoRepository.save(info);
        return info;
    }

    @Override
    public boolean existsProjectCode(String projectCode) {
        Info existProject = infoRepository.findProjectByProjectCode(projectCode);
        if(existProject != null){
            return true;
        }
        return false;
    }

    @Override
    public boolean existsProjectManger(String projectManger) {
        if(userRepository.findUserByName(projectManger)){
            return true;
        }
        return false;
    }

    @Override
    public boolean existsUserRole(String projectManger) {
        String roleId = userRepository.findIdByName(projectManger);
        String roleType = roleRepository.findAuthorityById(roleId);
        if(roleType.equals("ROLE_ProjectManger")){
            return true;
        }
        return false;
    }

    @Override
    public void insertProjectInfo(Info info) {
        infoRepository.save(info);
    }

    @Override
    public Info getProjectInfos(String projectCode) {
        return infoRepository.findInfoByProjectCode(projectCode);
    }


    @Override
    public List<String> getProjectNameList() {
        List<Info> infoList = infoRepository.findInfosByDelete(0);
        List<String> projectNameList = infoList.stream().map(info -> info.getProjectName()).collect(Collectors.toList());
        return projectNameList;
    }

    @Override
    public String getProjectCodeByProjectName(String projectName) {
        Info info = infoRepository.findInfoByProjectNameAndDelete(projectName , 0);
        String projectCode = info.getProjectCode();
        return projectCode;
    }
}